@cachly-dev/mcp-server 0.10.200 → 0.10.202
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -13
- package/dist/src/blosses-thema.js +1 -0
- package/dist/src/einblendung.js +4 -4
- package/dist/src/handlers/brain.js +31 -31
- package/dist/src/index.js +155 -155
- package/glama.json +1 -1
- package/hooks/cachly-ambient-einblendung.mjs +25 -25
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -234,21 +234,46 @@ Run `health` to see what is wired up in your editor. The full catalog is generat
|
|
|
234
234
|
|
|
235
235
|
```bash
|
|
236
236
|
npx @cachly-dev/mcp-server@latest autopilot # One command: signs in, configures every editor, fills the Brain from git
|
|
237
|
-
npx @cachly-dev/mcp-server@latest claim # Move a test Brain into your account, lessons included
|
|
238
|
-
npx @cachly-dev/mcp-server@latest demo # Preview your Brain from git history (no account needed)
|
|
239
|
-
npx @cachly-dev/mcp-server@latest bench # Run the recall benchmark (no sign-in needed)
|
|
240
|
-
npx @cachly-dev/mcp-server@latest autosetup # Interactive variant: pick editors yourself
|
|
241
|
-
npx @cachly-dev/mcp-server@latest health # Check token, API, editors and git hook
|
|
242
|
-
npx @cachly-dev/mcp-server@latest export # Write every lesson to lessons.md and lessons.jsonl
|
|
243
|
-
npx @cachly-dev/mcp-server@latest digest # Weekly Brain summary, shareable
|
|
244
|
-
npx @cachly-dev/mcp-server@latest share # Generate a shareable stats card
|
|
245
|
-
npx @cachly-dev/mcp-server@latest publish # Publish your Brain as an importable link (--public)
|
|
246
|
-
npx @cachly-dev/mcp-server@latest badge # Get a live README badge for your Brain
|
|
247
|
-
npx @cachly-dev/mcp-server@latest invite # Invite a teammate to share your Brain
|
|
248
|
-
npx @cachly-dev/mcp-server@latest index . # Index a project's code into the Brain (CI-friendly)
|
|
249
|
-
npx @cachly-dev/mcp-server@latest learn-git # Learn lessons from recent git commits
|
|
250
237
|
```
|
|
251
238
|
|
|
239
|
+
Every command below runs as `npx @cachly-dev/mcp-server@latest <command>`. Key and Brain
|
|
240
|
+
instance come from the environment or from `~/.cachly/credentials.json`, the file `autopilot` writes.
|
|
241
|
+
|
|
242
|
+
| Every day | |
|
|
243
|
+
|---|---|
|
|
244
|
+
| `status` | Lessons, recalls and team at a glance |
|
|
245
|
+
| `ambient-stats` | Tokens injected vs saved — the honest net, even when negative |
|
|
246
|
+
| `doctor` | Diagnose a broken or missing install, with the fix for each step |
|
|
247
|
+
| `health` | Check key, API, editor configs and git hook |
|
|
248
|
+
| `digest` | What your Brain learned this week, shareable |
|
|
249
|
+
|
|
250
|
+
| Set up | |
|
|
251
|
+
|---|---|
|
|
252
|
+
| `demo` | Preview your Brain from git history (no account needed) |
|
|
253
|
+
| `setup` (alias `autosetup`) | Interactive variant: pick editors yourself |
|
|
254
|
+
| `init --editor <id>` | Write the config for one editor, with flags |
|
|
255
|
+
| `claim` | Move a test Brain into your account, lessons included |
|
|
256
|
+
| `upgrade` | Check for updates |
|
|
257
|
+
|
|
258
|
+
| Your data | |
|
|
259
|
+
|---|---|
|
|
260
|
+
| `export` | Write every lesson to `lessons.md` and `lessons.jsonl` |
|
|
261
|
+
| `index [dir]` | Index a project's code into the Brain (CI-friendly) |
|
|
262
|
+
| `learn-git [repo]` | Learn lessons from recent git commits |
|
|
263
|
+
|
|
264
|
+
| Team & sharing | |
|
|
265
|
+
|---|---|
|
|
266
|
+
| `invite [email]` | Invite a teammate to share your Brain |
|
|
267
|
+
| `join <token>` | Accept a Brain invite |
|
|
268
|
+
| `share` | Generate a shareable stats card |
|
|
269
|
+
| `publish` | Publish your Brain as an importable link (`--public`) |
|
|
270
|
+
| `badge` | Get a live README badge for your Brain |
|
|
271
|
+
|
|
272
|
+
| More | |
|
|
273
|
+
|---|---|
|
|
274
|
+
| `bench` | Run the recall benchmark (no sign-in needed) |
|
|
275
|
+
| `tool-specs` / `openapi` | Tool definitions for other agent frameworks (OpenAI, Anthropic, LangChain, OpenAPI) |
|
|
276
|
+
|
|
252
277
|
The method behind `bench` is described in [BENCH.md](./BENCH.md).
|
|
253
278
|
|
|
254
279
|
> **Tip: learn from every merged PR.** Run `learn-git` in CI with the
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(t){return/^[a-z]+:?$/.test(t)}export{e as istBlossesThema};
|
package/dist/src/einblendung.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{readFileSync as T,existsSync as C,writeFileSync as R,mkdirSync as G,statSync as F,appendFileSync as V}from"node:fs";import{dirname as j,join as _}from"node:path";import{tmpdir as b}from"node:os";import{createHash as W}from"node:crypto";import{spawn as X}from"node:child_process";import{Einblendbestand as
|
|
1
|
+
import{readFileSync as T,existsSync as C,writeFileSync as R,mkdirSync as G,statSync as F,appendFileSync as V}from"node:fs";import{dirname as j,join as _}from"node:path";import{tmpdir as b}from"node:os";import{createHash as W}from"node:crypto";import{spawn as X}from"node:child_process";import{Einblendbestand as B,torWoerter as $}from"./einblendung-kern.js";import{rahmeEin as U}from"./einblendung-rahmen.js";import{istMarkiert as Q}from"./verdacht-marke.js";import{istBlossesThema as ee}from"./blosses-thema.js";import{leserText as te}from"./seltenheitsbestand.js";import{mischeMitLeser as z}from"./leser.js";import{LeserSicherung as ne,dateiSpeicher as re,frageLeser as se}from"./leser-sicherung.js";import{LESER_TIEFE_EINBLENDUNG as oe,LESER_ZEITLIMIT_MS as ie}from"./rangfolge-stellschrauben.js";import{stufeEinblendungNachVersion as le}from"./gueltigkeit-version.js";import{ARME as H,BASIS_MIN_BELEGE as ae,MERKMAL_KANDIDATEN as ce,OHNE_LERNEN as ue,entscheide as pe,leseArmZaehlung as fe,lernEinstellungen as he,lernenAuffrischen as me,merkeEntscheidung as de,neuerSatz as ge,sitzungsKennung as Ee,zugKennung as _e}from"./lernen.js";export*from"./einblendung-kern.js";import{belohnungMelden as ut,lernenAuffrischen as pt,lernEinstellungen as ft,ARME as ht}from"./lernen.js";const be=600*1e3,O=300*1e3,Se=10*1e3,Ae=2e3,ye=50,Ne=60*1e3;function ve(e,t){return t<O?{ttlMs:Se,sofort:!0}:e<ye?{ttlMs:Ne,sofort:!1}:{ttlMs:be,sofort:!1}}const P=8e3,Ie=60*1e3,D=120,J=oe,ke=1500,v=ie,we=_(b(),"cachly-ambient-netlog.jsonl");function Qe(e=process.cwd()){const t={apiUrl:process.env.CACHLY_API_URL||"https://api.cachly.dev",jwt:process.env.CACHLY_JWT||"",instanceId:process.env.CACHLY_BRAIN_INSTANCE_ID||""};if(t.jwt&&t.instanceId)return t;let n=e;for(let s=0;s<8;s++){const r=_(n,".mcp.json");if(C(r))try{const i=JSON.parse(T(r,"utf8"))?.mcpServers?.cachly?.env??{};if(t.apiUrl=t.apiUrl||i.CACHLY_API_URL||"https://api.cachly.dev",t.jwt=t.jwt||i.CACHLY_JWT||"",t.instanceId=t.instanceId||i.CACHLY_BRAIN_INSTANCE_ID||"",t.jwt&&t.instanceId)return t}catch{}const o=j(n);if(o===n)break;n=o}return t}function I(e){return W("sha1").update(e).digest("hex").slice(0,12)}function K(e){return _(b(),`cachly-ambient-bestand-${I(e)}.json`)}function Me(e){return _(b(),`cachly-leser-sicherung-${I(e)}.json`)}function Le(e,t="ambient-auffrischen"){return _(b(),`cachly-${t}-${I(e)}.lock`)}async function k(e,{fetchFn:t=fetch,zeitlimitMs:n=P}={}){try{const s=await t(`${e.apiUrl}/api/v1/instances/${e.instanceId}/export`,{headers:{Authorization:`Bearer ${e.jwt}`},signal:AbortSignal.timeout(n)});if(!s.ok)return null;const r=await s.json();return!Array.isArray(r?.lessons)||r.lessons.length===0&&typeof r.note=="string"&&r.note?null:r.lessons.map(o=>typeof o=="string"?xe(o):o).filter(o=>!!o&&typeof o=="object")}catch{return null}}function xe(e){try{return JSON.parse(e)}catch{return null}}function S(e,t,n="server"){const s=Date.now(),r=A(e),o=r?.seit??s;let i;n==="vorab"?i=t:n==="server"&&r?.vorab&&s-o<O&&(i=r.vorab);const a=n==="server"&&i?Te(t,i):t;try{G(j(e),{recursive:!0}),R(e,JSON.stringify({at:s,seit:o,lessons:a,...i?{vorab:i}:{}}),{mode:384})}catch{}return a}function Te(e,t){const n=new Set(e.map(s=>s.topic));return[...e,...t.filter(s=>!n.has(s.topic))]}function et(e,t){if(!e||t.length===0)return!1;const n=K(e);return(A(n)?.lessons.length??0)>0?!1:(S(n,t,"vorab"),!0)}function A(e){try{const t=JSON.parse(T(e,"utf8"));if(Array.isArray(t?.lessons)){const n=Number(t.at)||0;return{at:n,seit:Number(t.seit)||n,lessons:t.lessons,...Array.isArray(t.vorab)?{vorab:t.vorab}:{}}}}catch{}return null}function Ce(e,t,{zweck:n,ordner:s}={}){const r=Le(e.instanceId,n);try{if(C(r)&&Date.now()-F(r).mtimeMs<Ie)return!1;R(r,String(Date.now()),{mode:384})}catch{return!1}try{return X(process.execPath,t,{detached:!0,stdio:"ignore",...s?{cwd:s}:{},env:{...process.env,CACHLY_API_URL:e.apiUrl,CACHLY_JWT:e.jwt,CACHLY_BRAIN_INSTANCE_ID:e.instanceId}}).unref(),!0}catch{return!1}}async function Re(e,{force:t=!1,nebenlauf:n,abrufMs:s=P,lernen:r=!1,vorabSchliessen:o=!1,fetchFn:i}={}){if(!e.jwt||!e.instanceId)return{lessons:[],quelle:"nicht-eingerichtet"};const a=K(e.instanceId);if(t){const[m]=await Promise.all([k(e,{fetchFn:i,zeitlimitMs:s}),r?me(e,{fetchFn:i}):void 0]);if(m)return{lessons:S(a,m,o?"abschluss":"server"),quelle:"server"};const c=A(a);return c?{lessons:c.lessons,quelle:"platte-alt"}:{lessons:[],quelle:"server-nicht-erreichbar"}}const l=A(a);if(l){const m=Date.now(),c=ve(l.lessons.length,m-l.seit);if(m-l.at<c.ttlMs)return{lessons:l.lessons,quelle:"platte"};if(c.sofort){const h=await k(e,{fetchFn:i,zeitlimitMs:Math.min(s,Ae)});return h?{lessons:S(a,h),quelle:"server"}:{lessons:l.lessons,quelle:"platte-alt"}}return n&&Ce(e,n),{lessons:l.lessons,quelle:"platte-alt"}}const f=await k(e,{fetchFn:i,zeitlimitMs:s});return f?{lessons:S(a,f),quelle:"server"}:{lessons:[],quelle:"server-nicht-erreichbar"}}function w(e){return Math.ceil(String(e).length/4)}function M(e){const t=e.severity?`[${e.severity}] `:"",n=String(e.what_worked??"").replace(/\s+/g," ").trim(),s=n.length>D?`${n.slice(0,D)}\u2026`:n,r=typeof e.versionshinweis=="string"?` [${e.versionshinweis}]`:"";return`- ${t}${e.topic}${r}: ${s}`}const y={lessons:[],tokens:0,topScore:0,belege:0};function L(e,t,n){if(e.length===0)return{...y};const s=[];let r=0;e=le(e);for(const{lektion:o}of e.slice(0,t)){const i=w(M(o));if(r+i>n)break;s.push(o),r+=i}return{lessons:s,tokens:r,topScore:Math.round(e[0].punkte*100)/100,belege:e[0].belege}}function tt(e,t,{minBelege:n=2,topK:s=3,tokenBudget:r=600}={}){if(!Array.isArray(t)||t.length===0)return{...y};if($(e).length===0)return{...y};const o=new B(t).sortiere(e).filter(i=>i.belege>=n);return o.length===0?{...y}:L(o,s,r)}function je(e){return te(e,ke)}async function q(e,t,n,{zeitlimitMs:s=v,fetchFn:r}={}){if(!e?.jwt||!e?.instanceId||n.length===0)return{art:"ohne"};if(["0","off","aus","false"].includes(String(process.env.CACHLY_LESER||"").toLowerCase()))return{art:"ohne"};const o=new ne(re(Me(e.instanceId)));return se({url:`${e.apiUrl}/api/v1/rerank`,jwt:e.jwt,frage:t,texte:n,instanceId:e.instanceId,zeitlimitMs:s,fetchFn:r},o)}async function nt(e,t,n,s={}){const r=await q(e,t,n,s);return r.art==="punkte"?{scores:r.scores,provider:r.provider,ms:r.ms}:null}async function Y(e,t,n,{minBelege:s,tiefe:r,zeitlimitMs:o,fetchFn:i}){const a={sortiert:[],leser:"aus",leserMs:0};if(!Array.isArray(t)||t.length===0||$(e).length===0)return a;let l=new B(t).sortiere(e).filter(c=>c.belege>=s);if(l.length===0)return a;let f="aus",m=0;if(l.length>1&&r>0){const c=l.slice(0,r),d=l.slice(r),h=await q(n,e,c.map(E=>je(E.lektion)),{zeitlimitMs:o,fetchFn:i});h.art==="punkte"?(l=[...z(c.map(p=>p.punkte),h.scores,1).map(p=>({...c[p],leser:h.scores[p]})),...d],f=h.provider,m=h.ms):h.art==="uebersprungen"&&(f="uebersprungen")}return{sortiert:l,leser:f,leserMs:m}}async function rt(e,t,n,{minBelege:s=2,topK:r=3,tokenBudget:o=600,tiefe:i=J,zeitlimitMs:a=v,fetchFn:l}={}){const f=await Y(e,t,n,{minBelege:s,tiefe:i,zeitlimitMs:a,fetchFn:l});return{...L(f.sortiert,r,o),leser:f.leser,leserMs:f.leserMs}}function Be(e){if(!e.lessons.length)return"";const t=e.lessons.map(M).join(`
|
|
2
2
|
`);return`\u{1F9E0} Cachly Brain \u2014 relevant lessons for this task (auto-recall, ${e.lessons.length}):
|
|
3
3
|
${U(t)}
|
|
4
|
-
(ambient-recall \xB7 ~${e.tokens} tokens \xB7 match score ${e.topScore})`}const $e=5;function
|
|
4
|
+
(ambient-recall \xB7 ~${e.tokens} tokens \xB7 match score ${e.topScore})`}const $e=5;function st(e){const t=e.filter(o=>!Q(o));if(!t.length)return"";const n=t.filter(o=>{const i=String(o.topic??"");return!(/^auto:/.test(i)||ee(i))}),r=[...n.length?n:t].sort((o,i)=>(Number(i.recall_count)||0)-(Number(o.recall_count)||0)).slice(0,$e).map(M).join(`
|
|
5
5
|
`);return`\u{1F9E0} Cachly Brain \u2014 ambient recall active (${t.length} lessons). Top by proven reuse:
|
|
6
6
|
${U(r)}
|
|
7
|
-
(Relevant lessons for each task are auto-injected per prompt. ~${w(r)} tokens.)`}function
|
|
8
|
-
`)}catch{}return{kontext:N,auswahl:u,quelle:d,bestand:c.length,entscheidung:p}}export{P as ABRUF_TIMEOUT_MS,D as ANZEIGE_ZEICHEN,
|
|
7
|
+
(Relevant lessons for each task are auto-injected per prompt. ~${w(r)} tokens.)`}function ot(e,t){return t?JSON.stringify({hookSpecificOutput:{hookEventName:e,additionalContext:t}}):""}function Ue(e,t){return e.map((n,s)=>({x:n,rang:s,gezeigt:t.includes(n.lektion)})).filter(({rang:n,gezeigt:s})=>n<ce||s).map(({x:n,rang:s,gezeigt:r})=>({thema:String(n.lektion.topic??""),rang:s,punkte:Math.round(n.punkte*1e3)/1e3,belege:n.belege,leser:typeof n.leser=="number"&&Number.isFinite(n.leser)?Math.round(n.leser*1e3)/1e3:null,gezeigt:r}))}async function it(e,t,{nebenlauf:n,abrufMs:s,leser:r=!0,session:o=null,protokoll:i=!0,ereignis:a="UserPromptSubmit",editor:l="",lernen:f=!0,fetchFn:m}={}){const{lessons:c,quelle:d}=await Re(t,{nebenlauf:n,abrufMs:s,fetchFn:m}),h=he(),E=f&&h.aktiv&&a==="UserPromptSubmit"&&!!t.instanceId,p=E?pe({instanceId:t.instanceId,sitzung:o,prompt:e,zaehlung:fe(t.instanceId),einstellungen:h}):ue,x=H[p.arm]??H[0],g=await Y(e,c,t,{minBelege:ae,tiefe:r?J:0,zeitlimitMs:v,fetchFn:m}),u={...L(g.sortiert.filter(Z=>Z.belege>=x.minBelege),x.topK,600),leser:g.leser,leserMs:g.leserMs},N=p.kontrolle?"":Be(u);if(E&&g.sortiert.length>0&&de(t.instanceId,o,ge({sitzung:Ee(o),zug:_e(e),ereignis:a,editor:l,arm:p.arm,kontrolle:p.kontrolle,erkundet:p.erkundet,ausgewaehlt:u.lessons.length,kandidatenZahl:g.sortiert.length,belege:u.belege,topScore:u.topScore,leser:u.leser,leserMs:u.leserMs,quelle:d,bestand:c.length,kandidaten:Ue(g.sortiert,u.lessons)})),i)try{V(we,JSON.stringify({at:Date.now(),session:o,prompt_tokens:w(e),injected_tokens:N?u.tokens:0,matches:N?u.lessons.length:0,arm:p.arm,kontrolle:p.kontrolle,ausgewaehlt:u.lessons.length,top_score:u.topScore,belege:u.belege,leser:u.leser,leser_ms:u.leserMs,quelle:d,bestand:c.length})+`
|
|
8
|
+
`)}catch{}return{kontext:N,auswahl:u,quelle:d,bestand:c.length,entscheidung:p}}export{P as ABRUF_TIMEOUT_MS,D as ANZEIGE_ZEICHEN,ht as ARME,Se as BESTAND_TTL_JUNG_MS,Ne as BESTAND_TTL_KLEIN_MS,be as BESTAND_TTL_MS,Ae as JUNG_ABRUF_MS,O as JUNG_FENSTER_MS,ye as KLEIN_LEKTIONEN,v as LESER_HOOK_ZEITLIMIT_MS,ke as LESER_MAX_ZEICHEN,J as LESER_TIEFE,we as NETZ_PROTOKOLL,$e as SITZUNG_TOP_N,ut as belohnungMelden,ve as bestandFrist,K as bestandPfad,Te as ergaenzeUmVorab,w as estimateTokens,Re as holeBestand,ot as hookAusgabe,ft as lernEinstellungen,pt as lernenAuffrischen,q as leserAnfrageApi,nt as leserPunkteApi,je as leserText,z as mischeMitLeser,it as promptEinblendung,Be as promptKontext,M as renderLesson,Qe as resolveConfig,et as schreibeVorabBestand,tt as selectRelevant,rt as selectRelevantMitLeser,Me as sicherungsPfad,st as sitzungsKontext,Ce as starteNebenlauf};
|